﻿using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;

namespace Common.Extensions
{
    /// <summary>
    /// Sortierungserweiterungen für IENumerable
    /// </summary>
    public static class SortExtensions
    {
        /// <summary>
        /// Der Name des Properties nach dem sortiert werden soll
        /// </summary>
        public static string UrlSortName = "sortName";

        /// <summary>
        /// Gibt an ob ASC oder DESC sortiert werden soll
        /// </summary>
        public static string UrlSortType = "sortType";

        /// <summary>
        /// Sortierung für ASC
        /// </summary>
        public static string SortASC = "ASC";

        /// <summary>
        /// Sortierung für DESC
        /// </summary>
        public static string SortDESC = "DESC";

        /// <summary>
        /// Sortieren der Auflistung anhand der übergebenen Liste vom Typ T und hier wird nach dem Property gesucht was in der 
        /// URL als "sortName" übergeben wurde und nach diesem wird die Liste dann sortiert.
        /// </summary>
        /// <typeparam name="T">Typ Der Auflistung</typeparam>
        /// <param name="entityList">Liste die den Typ T enthält</param>
        /// <returns>Sortierte Liste, wenn die URL Parameter stimmen und alles übergeben wurde | Bei einem Fehler die Orginalliste unsortiert.</returns>
        public static IOrderedEnumerable<T> OrderByUrlParams<T>(this IEnumerable<T> entityList)
        {
            //die jeweiligen URL Parameter auslesen, die für die Sortierung der Spalten benötigt werden
            string urlSortName = HttpContext.Current.Request.Params[UrlSortName];
            string urlSortType = HttpContext.Current.Request.Params[UrlSortType];

            //Wenn der Name in der URL gefunden wurde, dann versuchden das Property im Typ T zu finden
            if (!string.IsNullOrEmpty(urlSortName))
            {
                //Heraussuchen des Properties vom Typ T für den Namen der in der URL übergeben wurde z.B. "Firstname"
                //Es kann auch nach Benutzerdefinierten Typen sortiert werden, wie z.B: EFCategory, dafür muss nur IComapeable bei dem Typ Implementiert sein.
                PropertyInfo prop = typeof(T).GetProperty(urlSortName);

                //Wenn das Property gefunden wurde, die Sortierung beginnen
                if (prop != null)
                {
                    if (!string.IsNullOrEmpty(urlSortType))
                    {
                        //Aufsteigende Sortierung vornehmen
                        if (urlSortType.ToLower() == SortASC.ToLower())
                        {
                            return entityList.OrderBy(p => prop.GetValue(p, null));
                        }

                        //absteigende Sortierung vornehmen
                        if (urlSortType.ToLower() == SortDESC.ToLower())
                        {
                            return entityList.OrderByDescending(p => prop.GetValue(p, null));
                        }

                        //Wenn keine Sortierrichtung in der URL angegeben wurde, dann einfach normal sortieren nach der passenden Spalte
                        return entityList.OrderBy(p => prop.GetValue(p, null));
                    }
                    else
                    {
                        //Wenn keine Sortierrichtung in der URL angegeben wurde, dann einfach normal sortieren nach der passenden Spalte
                        return entityList.OrderBy(p => prop.GetValue(p, null));
                    }
                }
            }

            //Die Liste unsortiert zurück geben
            return entityList.OrderBy(p=>p);
        }
    }
}